#coding: utf-8

import logging
from consts import *


class EntitiesExtractor:

    def __init__(self, ldb):
        self.ldb = ldb
        self.entities = {}
        self.prepositions = {}

    def load_entities(self, token):

        logging.debug('fetching entity for token: ' + token)
        loaded_entities = []
        #artifically create semantic entity for a number of a form (Число, 30000)
        if is_digit(token):
            return LoadedSemanticEntity(token,'(%s,%s)' % (SEMANTIC_ENTITIES.NUMBER, str(token)), 'натчисло',None, None, None, None)

        query_result = self.ldb.query_ldb(TABLE_NAMES.LSD, {'word': token.lower()})

        for entity in query_result:
            loaded_entity = LoadedSemanticEntity(
                token,
                entity[3],
                entity[4],
                entity[5],
                entity[6],
                entity[7],
                entity[8])
            loaded_entities.append(loaded_entity)
            #log fetched entity
            logging.debug('-------entity fetched!!!--------')
            logging.debug(entity)
        #NOTE: only first semantic entity is taken
        if loaded_entities:
            return loaded_entities[0]
        else:
            return loaded_entities


    def attach_modifiers_to_concept(self, tree, tagged_tokens_with_semantic_entities, concept_pos, modifier_pos):
        #code below attaches modifiers to concept
        nentity = None
        modifiers = []
        concept = ''
        for child in tree:

            #print 'child',child
            pos = child.pos
            sementity = tagged_tokens_with_semantic_entities[child.index].sementity
            if pos in modifier_pos:
                modifiers.append(separate_modifier(sementity.semsit))
            elif pos is  concept_pos:
                parts = separate_concept(sementity.semsit)
                concept += parts[0]
                if len(parts) > 1:
                    modifiers.extend(parts[1])
                nentity = sementity
#            elif pos == POS_TAGS.CONJUNCTION:
#                conjunction = ''
#                if child.token == LOGICAL_OPERATORS.AND:
#                    conjunction = 'AND'
#                elif child.token == LOGICAL_OPERATORS.OR:
#                    conjunction = 'OR'
#                concept += conjunction

        #print concept_pos, concept
        return NamedEntity(concept, nentity.get_sortlist(), modifiers)

    def extract_entities1(self, tree, tagged_tokens_with_semantic_entities):

        """
            Goes through the tree and finds named entities
        """

        try:
            #t.node contains node label ( S, NP , VP, etc...)
            tree.node
        except AttributeError:
            #that exception means 't' is tuple representing a leaf
            pass
        else:
            #bottom-up approach
            for child in tree:
                self.extract_entities1(child, tagged_tokens_with_semantic_entities)
            # Now we know that t.node is defined
            if tree.node == 'NP':

                self.entities[tree] = self.attach_modifiers_to_concept(tree, tagged_tokens_with_semantic_entities, POS_TAGS.NOUN, [POS_TAGS.ADJECTIVE, POS_TAGS.NUMBER])


            elif tree.node == 'PP':
                self.prepositions[tree] = 'N'
                notsign = ''
                for child in tree:
                    if child.pos is POS_TAGS.NOT:
                        notsign = '~'
                    elif child.pos is POS_TAGS.PREPOSITION:
                        self.prepositions[tree] = child.token.lower()
                    elif child.node == 'NP':

                        self.entities[tree] = self.entities[child]
                        self.entities.pop(child)
                        if notsign:
                            self.entities[tree].concept = notsign + self.entities[tree].concept


            elif tree.node == 'VP':

                self.entities[tree] = self.attach_modifiers_to_concept(tree, tagged_tokens_with_semantic_entities, POS_TAGS.VERB, [POS_TAGS.ADVERB])








class LoadedSemanticEntity:
    def __init__(self, token, semsit,st1,st2,st3,st4,comment):
        self.token = token
        self.semsit = semsit
        self.st1 = st1
        self.st2 = st2
        self.st3 = st3
        self.st4 = st4
        self.comment = comment

    def get_sortlist(self):
        """
            returns list containing sorts for an entity
        """
        result = []
        if self.st1:
            result.append(self.st1)
        if self.st2:
            result.append(self.st2)
        if self.st3:
            result.append(self.st3)
        if self.st4:
            result.append(self.st4)
        return result

    def build_entity(self):
        return NamedEntity(self.semsit,self.get_sortlist())



class NamedEntity:

    def __init__(self, concept, sorts, modifiers=None):
        self.concept = concept
        if modifiers:
            self.modifiers = modifiers
        else:
            self.modifiers = []
        self.sorts = sorts
        print self


    def add_modifier(self, modifier):
        self.modifiers.append(modifier)
        print self
        return self

    def get_sorts(self):
        return self.sorts

    def __str__(self):
        print self.concept + '*' + '*'.join(map(lambda x:'(%s,%s)' % (x[0],x[1]), self.modifiers))
        return ''


    def get_semantic_representation(self):
        return self.concept + '*' + '*'.join(map(lambda x:'(%s,%s)' % (x[0],x[1]), self.modifiers))

class ConjunctedNamedEntity(NamedEntity):
    def __init__(self, nentity1, nentity2, conjunction):
        self.conjunction = conjunction
        self.nentity1 = nentity1
        self.nentity2 = nentity2
        self.concept = 'conjuncted entity'
        self.sorts = nentity1.sorts

    def get_semantic_representation(self):
        return NamedEntity.get_semantic_representation(self.nentity1) + self.conjunction + NamedEntity.get_semantic_representation(self.nentity2)